package com.cskaoyan.javase.oop3._1interface._0introduction;

/**
 * 在之前的猫狗案例中，我们将Animal类设置为抽象类
 *      现在我们有了新需求：一部分猫和狗，经过了特殊训练，能够直立行走了。
 *      那么这群特殊的猫和狗，怎么描述它们呢？
 *
 * 首先想要需要重新定义类: SuperDog,SuperCat
 * 但是它们仍然是猫和狗,所以仍然需要继承Cat和Dog,然后新增直立行走的方法
 * 但是这样做:
 *
 * 1.一方面没有体现代码复用。
 * 2.更重要的是，没有体现出特殊训练的过程。
 *      假如还有一些动物也要直立行走，增加这个行为，如何体现出规范性、标准性呢？
 *      体现出它们是特殊的经过训练的动物呢？
 *
 * 规范和标志需要抽象方法来制定,所以我们可以把直立行走作为一个抽象方法,放入一个抽象类,然后让SuperDog,SuperCat去继承
 * 这样既有规范,也能够实现需求,两全其美
 * 但是这样能不能做到? 做不到,因为:
 *      1.Java不支持多继承,SuperDog,SuperCat不能再继承别的类了.
 *      2.这个直立行走抽象方法的抽象类和SuperDog,SuperCat没有"is-a"关系,这里也不应该使用继承
 *      3.抽象类是祖先类而存在的,直立行走抽象方法的抽象类不符合抽象类的定义规则
 *
 * 综上,我们确实需要规范,但这个规范不应该是抽象类.目前我们没有学过这种语法,需要一种新的语法/新的数据类型来完成需求
 * 这种新的数据类型,至少具有以下特点:
 *      1.不受类继承的多继承限制
 *      2.它和它的子类没有继承的"is-a"关系(言下之意不是继承)
 *      3.需要抽象方法
 *      4.它不应该是一个类class，应该只描述行为，不描述属性
 *      ....
 *      这种新的数据类型就是接口.
 *
 * 接口的语法：
 * 定义接口和定义类是差不多的，语法是：
 * [访问权限修饰符] interface 接口名{
 *     // 接口体
 * }
 * 1.接口和类class一样都属于引用数据类型,但是它们是平行的关系，相互独立，和注解类似。
 * 2.接口的访问权限修饰符和类class一样，也只有两种。
 * 3.接口名和类名一样，要遵循“大驼峰式”的命名规范。接口也是比较特殊，在给接口起名字时，可以以大写的字母“I”开头
 *      表示这是一个接口，以示区分。（这种命名不是必须的）
 *
 * 接口体的定义：
 * 接口中允许定义抽象方法。
 *
 * 接口的使用：
 * 接口定义完毕后，可以被一个类去“继承”，这种“继承”在Java中被称之为实现（implements）
 * 使用关键字：implements
 * 如果一个类存在继承和实现，应该先继承，再实现（顺序不能变）
 * 实现这个接口的类称之为接口的实现类，也可以认为是接口的子类。这个接口可以叫“父接口”，当然当成父类用也没关系。
 *
 * 同时需要注意的是：
 *      1.接口和它的子类之间不是继承关系，它们也没有“is-a”关系。我们用“like-a”来描述接口和它的子类的关系。接口表示功能的扩展，更关注于行为，关注于规范和标准。
 *      2.接口的实现，不是“单实现”的，而是允许“多实现”的。一个类可以实现多个接口，不限制个数。
 *
 *
 * @since 11:45
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // SuperCat有几种方式创建对象
        /*SuperCat sc = new SuperCat();
        Cat c = new SuperCat();
        c.shout();
        ((SuperCat) c).walkUpright();
        ISpecialSkill iss = new SuperCat();
        iss.walkUpright();
        ((SuperCat) iss).shout();*/
        ISpecialSkill iss;
        iss = new SuperCat();
        iss.walkUpright();
        iss = new SuperDog();
        iss.walkUpright();
    }
}


abstract class Animal {
    public abstract void shout();
}

class Cat extends Animal {
    @Override
    public void shout() {
        System.out.println("猫叫");
    }
}

class Dog extends Animal {
    @Override
    public void shout() {
        System.out.println("狗叫");
    }
}

class SuperCat extends Cat implements ISpecialSkill {

    // 接口中有抽象方法，需要接口的实现类实现
    @Override
    public void walkUpright() {
        System.out.println("我是超威蓝猫，我能走不是很正常吗？");
    }
}

class SuperDog extends Dog implements ISpecialSkill,IA {
    @Override
    public void walkUpright() {
        System.out.println("我是汪汪队队长，跟我走吧。");
    }
}

abstract class AbstractSkill {
    public abstract void walkUpright();
}

// 定义接口，表示对直立行走这个方法的抽象
interface ISpecialSkill {
    public abstract void walkUpright();
}
interface IA{}